home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / gnu / oleo-1_4.lha / oleo-1.4 / help.c < prev    next >
C/C++ Source or Header  |  1993-05-22  |  8KB  |  351 lines

  1. /*    Copyright (C) 1993 Free Software Foundation, Inc.
  2.  
  3. This program is free software; you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation; either version 2, or (at your option)
  6. any later version.
  7.  
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11. GNU General Public License for more details.
  12.  
  13. You should have received a copy of the GNU General Public License
  14. along with this software; see the file COPYING.  If not, write to
  15. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  16.  
  17. #include "global.h"
  18. #include "cmd.h"
  19. #include "key.h"
  20. #include "info.h"
  21. #include "forminfo.h"
  22. #include "help.h"
  23. #include "key.h"
  24. #include "io-utils.h"
  25.  
  26. #ifndef alloca
  27. #ifdef __GNUC__
  28. #define alloca __builtin_alloca
  29. #else /* __GNUC__ not defined.  */
  30. #if HAVE_ALLOCA_H
  31. #include <alloca.h>
  32. #else /* not HAVE_ALLOCA_H */
  33. #if defined (MSDOS) && !defined (__TURBOC__)
  34. #include <malloc.h>
  35. #else /* not MSDOS, or __TURBOC__ */
  36. #if defined(_AIX)
  37. #include <malloc.h>
  38.  #pragma alloca
  39. #endif /* not _AIX */
  40. #endif /* not MSDOS, or __TURBOC__ */
  41. #endif /* not HAVE_ALLOCA_H */
  42. #endif /* __GNUC__ not defined.  */
  43. #endif /* alloca not defined.  */
  44.  
  45.  
  46.  
  47. /* This reads one info buffer, writing another.  On each line,  
  48.  * occurences of [COMMAND] are replaced with keysequence names,
  49.  * if COMMAND is bound.
  50.  */
  51.  
  52. #ifdef __STDC__
  53. void
  54. expand_help_msg (struct info_buffer * out, struct info_buffer * in)
  55. #else
  56. void
  57. expand_help_msg (out, in)
  58.      struct info_buffer * out;
  59.      struct info_buffer * in;
  60. #endif
  61. {
  62.   int x;
  63.   struct line line;
  64.   struct line seq_buf;
  65.   int out_offset;
  66.   int rel_map = the_cmd_frame->top_keymap;
  67.  
  68.   if (the_cmd_frame->cmd && (the_cmd_arg.style == &keyseq_style))
  69.     rel_map = the_cmd_arg.val.key.cmd.code;
  70.  
  71.   print_info (out, "");
  72.   out_offset = out->len;
  73.   out->len += in->len;
  74.   out->text = (char **)ck_remalloc (out->text, out->len * sizeof (char *));
  75.   init_line (&line);
  76.   init_line (&seq_buf);
  77.   for (x = 0; x < in->len; ++x)
  78.     {
  79.       char * next_burst = in->text[x];
  80.       char * end_burst = index (next_burst, '[');
  81.       set_line (&line, "");
  82.       set_line (&seq_buf, "");
  83.       while (end_burst)
  84.     {
  85.       char * fn_start = end_burst + 1;
  86.       char * fn_end = index (fn_start, ']');
  87.       int vec;
  88.       struct cmd_func * cmd;
  89.       if (fn_end && (*fn_start == '[') && fn_end[1] == ']')
  90.         {
  91.           int map = map_idn (fn_start + 1, fn_end - fn_start - 1);
  92.           if (map < 0)
  93.         map = map_id ("universal");
  94.           rel_map = map;
  95.           catn_line (&line, next_burst, end_burst - next_burst);
  96.           next_burst = fn_end + 2;
  97.           end_burst = index (next_burst, '[');
  98.         }
  99.       else if (   fn_end
  100.            && !find_function (&vec, &cmd, fn_start, fn_end - fn_start))
  101.         {
  102.           catn_line (&line, next_burst, end_burst - next_burst);
  103.           if (search_map_for_cmd (&seq_buf, rel_map, vec,
  104.                       cmd - the_funcs[vec])) 
  105.         {
  106.           catn_line (&line, seq_buf.buf, strlen (seq_buf.buf));
  107.           set_line (&seq_buf, "");
  108.         }
  109.           else
  110.         {
  111.           catn_line (&line, "M-x ", 4);
  112.           catn_line (&line, fn_start, fn_end - fn_start);
  113.         }
  114.           next_burst = fn_end + 1;
  115.           end_burst = index (next_burst, '[');
  116.         }
  117.       else if (fn_end)
  118.         end_burst = index (fn_end + 1, '[');
  119.     }
  120.       catn_line (&line, next_burst, strlen(next_burst));
  121.       out->text[x + out_offset] = line.buf;
  122.       init_line (&line);
  123.     }
  124.   free_line (&seq_buf);
  125.   free_line (&line);
  126. }
  127.  
  128.  
  129.  
  130.  
  131. #ifdef __STDC__
  132. void
  133. describe_function (char * name)
  134. #else
  135. void
  136. describe_function (name)
  137.      char * name;
  138. #endif
  139. {
  140.   int vector;
  141.   struct cmd_func * cmd;
  142.   if (!(   !find_function (&vector, &cmd, name, strlen(name))
  143.     && cmd->func_doc))
  144.     io_error_msg ("%s is not a function.", name); /* no return */
  145.   
  146.   {
  147.     struct info_buffer * ib_disp = find_or_make_info ("help-buffer");
  148.     clear_info (ib_disp);
  149.     print_info (ib_disp, "");
  150.     print_info (ib_disp, "%s", name);
  151.     {
  152.       struct info_buffer ib;
  153.       for (ib.len = 0; cmd->func_doc[ib.len]; ++ib.len) ;
  154.       ib.text = cmd->func_doc;
  155.       ib.name = name;
  156.       expand_help_msg (ib_disp, &ib);
  157.     }
  158.   }
  159.  
  160.   {
  161.     static char buf[] = "{view-info help-buffer}";
  162.     run_string_as_macro (buf);
  163.   }
  164. }
  165.  
  166.  
  167.  
  168. #ifdef __STDC__
  169. void
  170. brief_describe_key (struct key_sequence * keyseq)
  171. #else
  172. void
  173. brief_describe_key (keyseq)
  174.      struct key_sequence * keyseq;
  175. #endif
  176. {
  177.   if (keyseq->cmd.vector < 0 && keyseq->cmd.code < 0)
  178.     io_info_msg ("%s is unbound", keyseq->keys->buf);
  179.   else
  180.     io_info_msg ("%s --> %s", keyseq->keys->buf,
  181.          the_funcs[keyseq->cmd.vector][keyseq->cmd.code].func_name);
  182. }
  183.  
  184. #ifdef __STDC__
  185. void
  186. describe_key (struct key_sequence * keyseq)
  187. #else
  188. void
  189. describe_key (keyseq)
  190.      struct key_sequence * keyseq;
  191. #endif
  192. {
  193.   if (keyseq->cmd.vector < 0 && keyseq->cmd.code < 0)
  194.     io_info_msg ("%s is unbound", keyseq->keys->buf);
  195.   else if (keyseq->cmd.vector < 0)
  196.     io_info_msg ("%s is a prefix leading to the keymap `%s'.",
  197.          keyseq->keys->buf, map_names[keyseq->cmd.code]);
  198.   else
  199.     describe_function
  200.       (the_funcs[keyseq->cmd.vector][keyseq->cmd.code].func_name); 
  201. }
  202.  
  203.  
  204. #ifdef __STDC__
  205. void
  206. where_is (char * name)
  207. #else
  208. void
  209. where_is (name)
  210. char * name;
  211. #endif
  212. {
  213.   struct line seqname;
  214.   int vec;
  215.   int code;
  216.   struct cmd_func * cmd;
  217.   
  218.   if (!find_function (&vec, &cmd, name, strlen(name)))
  219.     code = cmd - the_funcs[vec];
  220.   else if (map_id (name) >= 0)
  221.     {
  222.       code = map_id (name);
  223.       vec = -1;
  224.     }
  225.   else
  226.     io_error_msg ("%s is not a function.", name); /* no return */
  227.   code = cmd - the_funcs[vec];
  228.   init_line (&seqname);
  229.   set_line (&seqname, "");
  230.   
  231.   if (!search_map_for_cmd (&seqname, the_cmd_frame->top_keymap, vec, code))
  232.     io_info_msg ("%s is not on any keys.", name);
  233.   else
  234.     io_info_msg ("%s is bound to %s.", name, seqname.buf);
  235.   
  236.   free_line (&seqname);
  237. }
  238.  
  239.  
  240. /* Help for the context of the current complex command. */
  241.  
  242. #ifdef __STDC__
  243. void
  244. help_with_command (void)
  245. #else
  246. void
  247. help_with_command ()
  248. #endif
  249. {
  250.   if (!the_cmd_frame->cmd)
  251.     io_info_msg ("help-with-command: No command is executing now.");
  252.   describe_function (the_cmd_frame->cmd->func_name);
  253. }
  254.  
  255.  
  256.  
  257.  
  258.  
  259. /* Access to the help messages defined in forminfo.c
  260.  * These include documentation for formula functions and
  261.  * other miscelaneous doc strings.
  262.  *
  263.  * The info message NAME is permanently stored in an info-buffer
  264.  * called _info_NAME
  265.  */
  266.  
  267. #ifdef __STDC__
  268. void
  269. builtin_help (char * name)
  270. #else
  271. void
  272. builtin_help (name)
  273.      char * name;
  274. #endif
  275. {
  276.   char info_name[100];
  277.   struct info_buffer * ib;
  278.  
  279.   if (strlen (name) < sizeof (info_name - 20))
  280.     io_error_msg ("No built in help for %s.", name);
  281.  
  282.   sprintf (info_name, "_info_%s", name);
  283.   ib = find_info (info_name);
  284.  
  285.   if (!ib)
  286.     {
  287.       char ** msg = forminfo_text (name);
  288.       if (!msg)
  289.     {
  290.       msg = (char **)ck_malloc (sizeof (char *) * 2);
  291.       msg[0] = mk_sprintf ("No built in help for %s.", name);
  292.       msg[1] = 0;
  293.     }
  294.       ib = find_or_make_info (info_name);
  295.       ib->len = parray_len (msg);
  296.       ib->text = msg;
  297.     }
  298.  
  299.   {
  300.     char exp_name[200];
  301.     char command[250];
  302.     struct info_buffer * expanded;
  303.     sprintf (exp_name, "_expanded_%s", info_name);
  304.     expanded = find_or_make_info (exp_name);
  305.     clear_info (expanded);
  306.     expand_help_msg (expanded, ib);
  307.     sprintf (command, "{set-info %s}", exp_name);
  308.     run_string_as_macro (command);
  309.   }
  310. }
  311.  
  312. #ifdef __STDC__
  313. void
  314. make_wallchart_info (void)
  315. #else
  316. void
  317. make_wallchart_info ()
  318. #endif
  319. {
  320.   struct info_buffer * wc = find_or_make_info ("unexpanded_wallchart");
  321.   struct info_buffer * wc_expanded = find_or_make_info ("wallchart");
  322.   if (wc->len == 0)
  323.     {
  324.       char ** txt = forminfo_text ("keybindings-wallchart");
  325.       if (!txt)
  326.     io_error_msg ("<bug> Wallchart is missing!");
  327.       wc->len = parray_len (txt);
  328.       wc->text = txt;
  329.     }
  330.   clear_info (wc_expanded);
  331.   expand_help_msg (wc_expanded, wc);
  332. }
  333.  
  334.  
  335. #ifdef __STDC__
  336. void
  337. write_info (char * info, FILE * fp)
  338. #else
  339. void
  340. write_info (info, fp)
  341.      char * info;
  342.      FILE * fp;
  343. #endif
  344. {
  345.   struct info_buffer * ib = find_or_make_info (info);
  346.   int x;
  347.   for (x = 0; x < ib->len; ++x)
  348.     fprintf (fp, "%s\n", ib->text[x]);
  349. }
  350.  
  351.